/*文件上传
 * ,文件压缩上传...
 * ,HTML5上传
 * RandyJie 2016-11-16
 * <pre> 
 * 2016-11-16 22:21:16
 * 	提供的调用 jquery fn html5uploader
 *  提供的方法 $('xx').html5uploader('upload'); -- 仅auto:false时有效
 *  关于参数:请参考defaults
 *  关于事件:请参考defaults
 *  
 *
 * DEMO:
    $('#xxx').html5uploader({url:wsc.config().get('user','/fileupload/base64image'),onUploadSuccess:function(d){
		console.log(d);
	},beforeSend: function (xhr) {
		 var header = $('meta[name=_csrf_header]').attr('content');
		 var token  = $('meta[name=_csrf]').attr('content');
    		xhr.setRequestHeader(header, token);
    }});
	$('#xwe').bind('click',function(){
		$('#xxx').html5uploader('upload');
	})
 *
 */
(function($) {
	"use strict";
	$.fn.html5uploader = function(opts){
		if(opts&&opts==='upload'){
			this.each(function(){
				uploadevent(this);
			});
			return;
		}
		var defaults = {
				url:'',//文件提交的地址
				auto:false,//自动上传
				multi:false,//默认允许选择多个文件 --暂时没有实现
				buttonText:'选择图片',//上传按钮上的文字
				buttonClass:'',//上传按钮的样式
				maxsize:1024*10,//文件最大大小 超过这个大小就会进行压缩  -- 暂时没做...
				quality:0.9,//图片质量 压缩的力度 最大1 最小0.1
				maxwidth:200,//最大宽度 超过就会进行缩放(其实是像素缩放 w*h)
				maxheight:200,//最大高度 超过就会进行缩放(其实是像素缩放 w*h)
				beforeSend:function(xhr){},
				onCompressed:function(data){},//图片压缩完成动作 data: {target:元素,imagedata:data}
				onChooseFile:function(){},//选择完图片时
				onUploadStart:function(){},//上传开始时的动作
				onUploadSuccess:function(){},//上传成功的动作
				onUploadComplete:function(){},//上传完成的动作
				onUploadError:function(){}, //上传失败的动作
				onInit:function(){}//初始化时的动作
				};
		var option = $.extend(defaults,opts);
		var formatFileSize = function(size){
			if (size> 1024 * 1024){
				size = (Math.round(size * 100 / (1024 * 1024)) / 100).toString() + 'MB';
				}
			else{
				size = (Math.round(size * 100 / 1024) / 100).toString() + 'KB';
				}
			return size;
		}
		this.each(function(){
			var _this = $(this);
			var inputstr = '<input class="uploadfile" style="position: absolute; top: 0;margin: 0;opacity: 0;cursor:pointer;" type="file" ';
			inputstr += '/>';
			var inputstr2 = '<a style="border: 1px solid #5ab96f;border-radius: 5px; margin-left:1rem" href="javascript:void(0)" class="uploadfilebtn '+option.buttonClass+'">';
			inputstr2 += option.buttonText;
			inputstr2 += '上传</a>';
			var fileInputButton = $(inputstr);
			fileInputButton.css('width',_this.width());
			fileInputButton.css('height',_this.height());
			_this.append(fileInputButton);
			_this.append(inputstr2);

			initEvents(this,option);
			_this.data('option',option);
		});
	}

  var initEvents = function(upele,ops){
	  var $ele = $(upele);
	  var $uploadfilebtn = $ele.find('.uploadfilebtn');
	  var $filechooser = $ele.find('.uploadfile');

	  $uploadfilebtn.bind('click',function(){
		  $filechooser.click();
	  });
	  $filechooser.bind('change', function(){
		  var files = Array.prototype.slice.call(this.files);
		  files.forEach(function(file, i) {
		      if (!/^image(.*)/.test(file.type)){
    		      if(ops.onUploadError && ops.onUploadError instanceof Function){
    				  ops.onUploadError({target:upele,error:'请选择一张图片.'});
    		  	  }
		       return;
		      }
		      if(ops.onChooseFile && ops.onChooseFile instanceof Function){
		          ops.onChooseFile({target:upele});
		      }
		      var reader = new FileReader();
		      reader.onload = function() {
		    	  var result = this.result;
		          var img = new Image();
		          img.src = result;

		          if (img.complete) {
		              callback();
		            } else {
		              img.onload = callback;
		            }
		          function callback() {
		              var data = compressImg(img,ops);
		              if(ops.onCompressed && ops.onCompressed instanceof Function){
		            	  ops.onCompressed({target:upele,imagedata:data,size:data.length});
		              }
		              img = null;
		              /*拿到压缩对象 next上传*/
		              if(ops.auto){
		            	  uploader(upele,data,ops);
		              }else{
		            	  $ele.data("imagedata",data);
		              }
		           }
		      };
		      reader.readAsDataURL(file);
		  })
	  });

	  /*init end*/
	  if(ops.onInit && ops.onInit instanceof Function){
    	  ops.onInit({target:upele});
      }
  };

  var canvas = document.createElement("canvas");
  var ctx = canvas.getContext('2d');
  //    瓦片canvas
  var tCanvas = document.createElement("canvas");
  var tctx = tCanvas.getContext("2d");
  /*压缩图片*/
  var compressImg = function(img, ops) {
    var initSize = img.src.length;
    var width = img.width;
    var height = img.height;
    //如果图片大于 预计像素 则进行缩放
    var _maxxs = ops.maxwidth*ops.maxheight;
	var ratio;
	if ((ratio = width * height / _maxxs) > 1) {
	  ratio = Math.sqrt(ratio);
	  width /= ratio;
	  height /= ratio;
	} else {
	  ratio = 1;
	}
	canvas.width = width;
	canvas.height = height;
	//铺底色
	ctx.fillStyle = "#fff";
	ctx.fillRect(0, 0, canvas.width, canvas.height);
	//如果图片像素大于100万则使用瓦片绘制
	var count;
	if ((count = width * height / 1000000) > 1) {
	  count = ~~(Math.sqrt(count) + 1); //计算要分成多少块瓦片
	//计算每块瓦片的宽和高
	  var nw = ~~(width / count);
	  var nh = ~~(height / count);
	  tCanvas.width = nw;
	  tCanvas.height = nh;
	  for (var i = 0; i < count; i++) {
	    for (var j = 0; j < count; j++) {
	      tctx.drawImage(img, i * nw * ratio, j * nh * ratio, nw * ratio, nh * ratio, 0, 0, nw, nh);
	      ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh);
	    }
	  }
	} else {
	  ctx.drawImage(img, 0, 0, width, height);
	}
	//进行压缩
	var ndata = canvas.toDataURL('image/jpeg', 0.9);
//	console.log('压缩前：' + initSize);
//	console.log('压缩后：' + ndata.length);
//	console.log('压缩率：' + ~~(100 * (initSize - ndata.length) / initSize) + "%");
	tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0;
	return ndata;
  }
  var uploadevent=function(ele){
	  var _this = $(ele);
	  var _ops = _this.data('option');
	  var _imagedata = _this.data('imagedata');
	  if(_ops && _imagedata){
		  if(_imagedata.length>10){
			  uploader(ele,_imagedata,_ops);
			  return true;
		  }else{
			  if(_ops.onUploadError && _ops.onUploadError instanceof Function){
				  _ops.onUploadError({target:ele,error:'请选择一张图片.'});
		  	  }
		  }
	  }else
		  return false;
  }

  /*上传*/
  var uploader = function(ele,imgdata,ops){
	  if(ops.onUploadStart && ops.onUploadStart instanceof Function){
    	  ops.onUploadStart({target:ele,imagedata:imgdata});
      }
	  $.ajax({
          type: 'POST',
          url: ops.url,
          data:{file:imgdata},
          dataType: 'json',
          xhrFields: {
              withCredentials: true
  	      },beforeSend: function (xhr) {
  	    	if(ops.beforeSend && ops.beforeSend instanceof Function){
  	    	  ops.beforeSend(xhr);
  	    	}
  	      },
  	      crossDomain: true,
	    success: function(data){
	    	if(ops.onUploadComplete && ops.onUploadComplete instanceof Function){
	  	    	  ops.onUploadComplete({target:ele,data:data});
	  	    }
	      if(data.state == "suc"){
	    	  if(ops.onUploadSuccess && ops.onUploadSuccess instanceof Function){
	  	    	  ops.onUploadSuccess({target:ele,data:data});
	  	      }
	      	}else{
	      	  if(ops.onUploadError && ops.onUploadError instanceof Function){
		  	      ops.onUploadError({target:ele,error:data.msg,data:data});
		  	  }
	      	}
	      },
	      error: function(req, status, ex) {
	    	var errmsg;
	      	if(req.responseJSON){
	      		if(req.responseJSON.msg){
	      			errmsg = req.responseJSON.msg;
            	}else{
            		errmsg = req.responseJSON.error;
            	}
	      	}
	      	if(ops.onUploadError && ops.onUploadError instanceof Function){
		  	      ops.onUploadError({target:ele,error:errmsg});
		  	}
	      	console.error('error:'+status);
	      }
	  });
  };


})(jQuery);
